#include "Global.h"

void _debugTupleDetail(std::ostream&, bool) {}

template <typename First, typename ... Last>
void _debugTupleDetail(std::ostream& os, bool bFst, First&& first, Last&& ... last)
{
	if (!bFst)
		os << ", ";

	os << first;
	_debugTupleDetail(os, false, last...);
}

template <typename Tuple, size_t... Indexes>
void _debugTupleDetail(std::ostream& os, Tuple&& tp, std::index_sequence<Indexes...>)
{
	_debugTupleDetail(os, true, std::get<Indexes>(move(tp)) ...);
}


template <typename... Args>
void debugTuple(std::ostream& os, std::tuple<Args...>& tp)
{
	_debugTupleDetail(os, tp, std::index_sequence_for<Args...>());
}

template <typename Tuple>
void _tokArgs(std::ostream& os, Tuple&& t)
{
	os << "[";
	debugTuple(os, t);
	os << "]" << std::endl;
	os << "[None]" << std::endl;
}

template <typename Tuple, typename First, typename ... Last>
void _tokArgs(std::ostream& os, Tuple&& t, First&& first, Last&& ... last)
{
	if (STR2TAG64(first) == TAG64('a', 'r', 'g', 's'))
	{
		os << "[";
		debugTuple(os, t);
		os << "]" << std::endl;
		os << "[";
		_debugTupleDetail(os, true, std::forward<Last>(last)...);
		os << "]" << std::endl;
	}
	else
	{
		_tokArgs(os, std::tuple_cat(t, std::forward_as_tuple(first)), std::forward<Last>(last)...);
	}
}

template <typename... Args>
void tokArgs(std::ostream& os, Args&&... args)
{
	_tokArgs(os, std::tuple<>(), std::forward<Args>(args)...);
}

int main()
{
#if 0
	auto t = std::make_tuple(1, "hello", "args", 2, "go");
	std::cout << "[";
	debugTuple(std::cout, t);
	std::cout << "]" << std::endl;

	std::cout << "[";
	std::tuple<> t1;
	debugTuple(std::cout, t1);
	std::cout << "]" << std::endl;
	std::cout << "[";
	std::tuple<> t2;
	debugTuple(std::cout, t2);
	std::cout << "]" << std::endl;
	std::cout << "[";
	auto t3 = tuple_cat(t, t1, t2, t);
	debugTuple(std::cout, t3);
	std::cout << "]" << std::endl;
#endif

	std::cout << 1 << std::endl;
	tokArgs(std::cout, 1, "hello", "args", 2, "go");
	std::cout << 2 << std::endl;
	tokArgs(std::cout, 1, "hello", "args");
	std::cout << 3 << std::endl;
	tokArgs(std::cout, 1, "hello");

	return 0;
}